﻿using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using wolfSSL.CSharp;

namespace Hongsh.Pay.Client.Proxy.Ssl {
    // Token: 0x02000021 RID: 33
    public class SSLStream : Stream {
        // Token: 0x17000059 RID: 89
        // (get) Token: 0x060000E5 RID: 229 RVA: 0x00002A33 File Offset: 0x00000C33
        public override bool CanRead {
            get {
                return true;
            }
        }

        // Token: 0x1700005A RID: 90
        // (get) Token: 0x060000E6 RID: 230 RVA: 0x00002A33 File Offset: 0x00000C33
        public override bool CanWrite {
            get {
                return true;
            }
        }

        // Token: 0x1700005B RID: 91
        // (get) Token: 0x060000E7 RID: 231 RVA: 0x00002A36 File Offset: 0x00000C36
        public override bool CanSeek {
            get {
                return false;
            }
        }

        // Token: 0x1700005C RID: 92
        // (get) Token: 0x060000E8 RID: 232 RVA: 0x00002A39 File Offset: 0x00000C39
        public override long Length {
            get {
                return -1L;
            }
        }

        // Token: 0x1700005D RID: 93
        // (get) Token: 0x060000E9 RID: 233 RVA: 0x00002A44 File Offset: 0x00000C44
        // (set) Token: 0x060000EA RID: 234 RVA: 0x00002A4F File Offset: 0x00000C4F
        public override long Position {
            get => 0L;
            set => throw new NotImplementedException();
        }

        // Token: 0x060000EB RID: 235 RVA: 0x00002A56 File Offset: 0x00000C56
        public override void Flush() {
        }

        // Token: 0x060000EC RID: 236 RVA: 0x00002A4F File Offset: 0x00000C4F
        public override long Seek(long offset, SeekOrigin origin) {
            throw new NotImplementedException();
        }

        // Token: 0x060000ED RID: 237 RVA: 0x00002A4F File Offset: 0x00000C4F
        public override void SetLength(long value) {
            throw new NotImplementedException();
        }

        // Token: 0x060000EE RID: 238 RVA: 0x0000AF08 File Offset: 0x00009108
        public override int Read(byte[] buffer, int offset, int count) {
            int num = buffer.Length - offset;
            if (count > num) {
                count = num;
            }
            int result;
            if (num <= 0) {
                result = 0;
            }
            else {
                byte[] array = (offset == 0) ? buffer : new byte[count];
                int num2 = wolfssl.read(SSL, array, array.Length);
                if (offset != 0) {
                    Buffer.BlockCopy(array, 0, buffer, offset, num2);
                }
                result = num2;
            }
            return result;
        }

        // Token: 0x060000EF RID: 239 RVA: 0x0000AF64 File Offset: 0x00009164
        public override void Write(byte[] buffer, int offset, int count) {
            byte[] array = buffer;
            if (offset > 0) {
                array = new byte[count];
                Buffer.BlockCopy(buffer, offset, array, 0, count);
            }
            wolfssl.write(SSL, array, count);
        }

        // Token: 0x060000F0 RID: 240 RVA: 0x00002A58 File Offset: 0x00000C58
        public override void Close() {
            wolfssl.CTX_free(SSLCTX);
            wolfssl.shutdown(SSL);
            wolfssl.free(SSL);
            Socket.Close();
        }

        // Token: 0x1700005E RID: 94
        // (get) Token: 0x060000F1 RID: 241 RVA: 0x00002A87 File Offset: 0x00000C87
        public Socket Socket { get; }

        // Token: 0x060000F2 RID: 242 RVA: 0x00002A8F File Offset: 0x00000C8F
        private SSLStream(Socket fd, IntPtr ctx, IntPtr ssl) {
            //Class15.cwcZ3SWztHroi();
            //base..ctor();
            Socket = fd;
            SSLCTX = ctx;
            SSL = ssl;
        }

        // Token: 0x060000F3 RID: 243 RVA: 0x0000AF98 File Offset: 0x00009198
        public static SSLStream AuthenticateAsServer(Socket fd, string filePEM) {
            return AuthenticateAsServer(fd, filePEM, filePEM);
        }

        // Token: 0x060000F4 RID: 244 RVA: 0x0000AFB0 File Offset: 0x000091B0
        public static SSLStream AuthenticateAsServer(Socket fd, string fileCert, string fileKey) {
            IntPtr intPtr = SSLCreateCtx(fd, fileCert, fileKey);
            SSLStream result;
            if (intPtr == IntPtr.Zero) {
                result = null;
            }
            else {
                IntPtr intPtr2 = smethod_0(fd, intPtr);
                if (intPtr2 == IntPtr.Zero) {
                    wolfssl.CTX_free(intPtr);
                    result = null;
                }
                else {
                    result = new SSLStream(fd, intPtr, intPtr2);
                }
            }
            return result;
        }

        // Token: 0x060000F5 RID: 245 RVA: 0x00002AB1 File Offset: 0x00000CB1
        private static void standard_log(int lvl, object msg) {
            Console.WriteLine(msg);
        }

        // Token: 0x060000F6 RID: 246 RVA: 0x0000B000 File Offset: 0x00009200
        private static IntPtr SSLCreateCtx(object fd, string fileCert, string fileKey) {
            wolfssl.SetLogging(new wolfssl.loggingCb(SSLStream.standard_log));
            wolfssl.Init();
            Console.WriteLine("Calling ctx Init from wolfSSL");
            IntPtr intPtr = wolfssl.CTX_new(wolfssl.usev23_server());
            IntPtr result;
            if (intPtr == IntPtr.Zero) {
                Console.WriteLine("Error in creating ctx structure");
                result = IntPtr.Zero;
            }
            else {
                Console.WriteLine("Finished init of ctx .... now load in cert and key");
                if (!File.Exists(fileCert) || !File.Exists(fileKey)) {
                    Console.WriteLine("Could not find cert or key file");
                    wolfssl.CTX_free(intPtr);
                    result = IntPtr.Zero;
                }
                else if (wolfssl.CTX_use_certificate_file(intPtr, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) {
                    Console.WriteLine("Error in setting cert file");
                    wolfssl.CTX_free(intPtr);
                    result = IntPtr.Zero;
                }
                else if (wolfssl.CTX_use_PrivateKey_file(intPtr, fileKey, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) {
                    Console.WriteLine("Error in setting key file");
                    wolfssl.CTX_free(intPtr);
                    result = IntPtr.Zero;
                }
                else {
                    StringBuilder stringBuilder = new StringBuilder(new string(' ', 4096));
                    int num = wolfssl.get_ciphers(stringBuilder, 4096);
                    Console.WriteLine("Ciphers : " + stringBuilder.ToString());
                    wolfssl.CTX_SetMinDhKey_Sz(intPtr, 128);
                    wolfssl.CTX_SetTmpDH_file(intPtr, new StringBuilder(intPtr.ToInt32().ToString() + ".pem"), wolfssl.SSL_FILETYPE_PEM);
                    result = intPtr;
                }
            }
            return result;
        }

        // Token: 0x060000F7 RID: 247 RVA: 0x0000B168 File Offset: 0x00009368
        private static IntPtr smethod_0(Socket fd, IntPtr ctx) {
            new StringBuilder(1024);
            IntPtr intPtr = wolfssl.new_ssl(ctx);
            IntPtr result;
            if (intPtr == IntPtr.Zero) {
                wolfssl.CTX_free(ctx);
                result = IntPtr.Zero;
            }
            else {
                Console.WriteLine("Connection made wolfSSL_accept ");
                if (wolfssl.set_fd(intPtr, fd) != wolfssl.SUCCESS) {
                    Console.WriteLine(wolfssl.get_error(intPtr));
                    result = IntPtr.Zero;
                }
                else if (wolfssl.accept(intPtr) != wolfssl.SUCCESS) {
                    Console.WriteLine(wolfssl.get_error(intPtr));
                    result = IntPtr.Zero;
                }
                else {
                    Console.WriteLine("SSL version is " + wolfssl.get_version(intPtr));
                    Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(intPtr));
                    result = intPtr;
                }
            }
            return result;
        }

        // Token: 0x04000072 RID: 114
        private readonly IntPtr SSL;

        // Token: 0x04000073 RID: 115
        private readonly IntPtr SSLCTX;
    }
}
